package controller.factory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import app.ModelConstants.StatechartComponentType;
import util.Utils;
import model.StatechartComponent;
import model.uml.connector.ConditionConnector;
import model.uml.connector.DeepHistoricConnector;
import model.uml.connector.HistoricConnector;
import model.uml.connector.SwitchConnector;
import model.uml.connector.SynchronizationBar;
import model.uml.connector.TerminationConnector;
import model.uml.note.Note;
import model.uml.note.NoteLink;
import model.uml.state.CompositeState;
import model.uml.state.EndState;
import model.uml.state.InitialState;
import model.uml.state.ParallelState;
import model.uml.state.SimpleState;
import model.uml.transition.Transition;
import model.util.Point;

public class StatechartComponentFactory {

	private static final Logger log = LoggerFactory
			.getLogger(StatechartComponentFactory.class);
	
	private final static StatechartComponentFactory instance = new StatechartComponentFactory();

	public final static StatechartComponentFactory instance() {
		return instance;
	}

	public StatechartComponent createComponent(StatechartComponentType componentType, Long parentComponentId, Point parentRelativeLocation) {
		StatechartComponent component = null;
		switch (componentType) {

		case INITIAL_STATE:
			component = new InitialState(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case SIMPLE_STATE:
			component = new SimpleState(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case PARALLEL_STATE:
			component = new ParallelState(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case COMPOSITE_STATE:
			component = new CompositeState(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case END_STATE:
			component = new EndState(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case CONDITION_CONNECTOR:
			component = new ConditionConnector(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case HISTORIC_CONNECTOR:
			component = new HistoricConnector(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case DEEP_HISTORIC_CONNECTOR:
			component = new DeepHistoricConnector(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case SWITCH_CONNECTOR:
			component = new SwitchConnector(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case SYNCHRONIZATION_BAR:
			component = new SynchronizationBar(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case TERMINATION_CONNECTOR:
			component = new TerminationConnector(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case NOTE:
			component = new Note(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		case NOTE_LINK:
			component = new NoteLink(getUniqueID(), parentComponentId);
			break;
		case TRANSITION:
			component = new Transition(getUniqueID(), parentComponentId, parentRelativeLocation);
			break;
		default:
			log.warn("missing implementation for " + componentType.name());
			break;
		}
		return component;
	}

	private Long getUniqueID() {
		return Utils.getUID();
	}

}
